<?php

namespace org\copperforest\oak\resources;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of Resource
 *
 * @author agama
 */
class Resource extends ResponseNode
{
    
    protected $_ancestorsvalues = array( );
    static protected $_antecesors; //antecesor cache

    //TENGO QUE HACERLO RECURSIVO
    //en las clases hojas se establecerán los atributos (metodo __set) antes que se ejecute el constructor
    //en las clases nodo se ejecutará el constructor y luego se establecerán los atributos
    //No está asegurado que en la ejecución del constructor tenga los datos establecidos
    //Cuando se sobreescriba tiene que llamarse a este

    function __construct() 
    {
        parent::__construct();

        $this->_evalParent();
    }

    
    //tengo que establecer por rodas si se ha creado el padre, 
    protected function _evalParent()
    {

        if ( !empty( $this->_ancestorsvalues ) && isset( $this->_ancestorsvalues[ 'classname' ] ) ) {

            if ( !isset( self::$_antecesors[ $this->_ancestorsvalues[ 'classname' ] ] ) )
                    self::$_antecesors[ $this->_ancestorsvalues[ 'classname' ] ] = array(
                        );

            if ( is_array( $this->_ancestorsvalues[ 'id' ] ) ) {

                $idlong = count( $this->_ancestorsvalues[ 'id' ] );

                $pointer = &self::$_antecesors[ $this->_ancestorsvalues[ 'classname' ] ]; //puntero a un array

                for ( $i = 0; $i < $idlong; $i++ ) {

                    if ( $i == $idlong - 1 ) {

                        if ( isset( $pointer[ $this->_ancestorsvalues[ 'id' ][ $i ] ] ) ) { //existe el objeto
                            unset( $this->_ancestorsvalues );
                            $this->parent = $pointer[ $this->_ancestorsvalues[ 'id' ][ $i ] ];
                        } else {  //no existe
                            $this->parent = new $this->_ancestorsvalues[ 'classname' ]();

                            foreach ( $this->_ancestorsvalues as $k => $v )
                                    $this->parent->$k = $v;

                            unset( $this->_ancestorsvalues );

                            $this->parent->_evalParent();

                            $pointer[ $this->_ancestorsvalues[ 'id' ][ $i ] ] = $this->parent;
                        }
                    } else if ( isset( $pointer[ $this->_ancestorsvalues[ 'id' ][ $i ] ] ) )
                            $pointer = &$pointer[ $this->_ancestorsvalues[ 'id' ][ $i ] ];
                    else
                            $pointer[ $this->_ancestorsvalues[ 'id' ][ $i ] ] = array(
                                );
                }
            }
            else {

                if ( !isset( $this->_ancestorsvalues[ 'id' ] ) ){
                    //se debe poder determinar la clase de la lista a usar con los parametros de la oonsulta SQLs
                    
                    $this->parent = new $this->_ancestorsvalues[ 'classname' ]();

                    foreach ( $this->_ancestorsvalues as $k => $v )
                            $this->parent->$k = $v;
                    
                }
                else if ( !isset( self::$_antecesors[ $this->_ancestorsvalues[ 'classname' ] ][ $this->_ancestorsvalues[ 'id' ] ] ) ) {

                    $this->parent = new $this->_ancestorsvalues[ 'classname' ]();

                    foreach ( $this->_ancestorsvalues as $k => $v )
                            $this->parent->$k = $v;



                    $this->parent->_evalParent();

                    self::$_antecesors[ $this->_ancestorsvalues[ 'classname' ] ][ $this->_ancestorsvalues[ 'id' ] ] = $this->parent;
                } else {
                    $this->parent = self::$_antecesors[ $this->_ancestorsvalues[ 'classname' ] ][ $this->_ancestorsvalues[ 'id' ] ];
                }

                unset( $this->_ancestorsvalues );
            }

            $this->parent->addChild( $this );
        }
    }

    public function __set( $name, $value )
    {

        if ( substr( $name, 0, 3 ) === 'id[' && substr( $name, -1, 1 ) === ']' ) {

            if ( !is_array( $this->id ) ) $this->id = array( );

            if ( substr( $name, 3, 1 ) == ']' ) $this->id[ ] = $value;
            else $this->id[ ( int ) substr( $name, 3, -1 ) ] = $value;
        }
        else if ( substr( $name, 0, 2 ) === '_' ) {

            $campo = substr( $name, 2 );

            if ( substr( $campo, 0, 3 ) === 'id[' && substr( $campo, -1, 1 ) === ']' ) {

                if ( !is_array( $this->_ancestorsvalues[ 'id' ] ) )
                        $this->_ancestorsvalues[ 'id' ] = array( );

                if ( substr( $campo, 3, 1 ) == ']' )
                        $this->_ancestorsvalues[ 'id' ][ ] = $value;
                else
                        $this->_ancestorsvalues[ 'id' ][ ( int ) substr( $campo,
                                    3, -1 ) ] = $value;
            }
            else $this->_ancestorsvalues[ $campo ] = $value;
        }
    }

    
    
 
    
    
    static function _getAncestors( $childs )
    {
        $parents = array( );

        //los hijos del mismo padre suelen venir juntos??

        foreach ( $childs as $c ) {

            $current = $c;

            while ( $current->parent != null )
                $current = $current->parent;

            $found = false;
            foreach ( $parents as $p ) {
                if ( $p === $current ) {
                    $found = true;
                    break;
                }
            }

            if ( !$found ) $parents[ ] = $current;
        }

        self:_clear();

        return $parents;
    }

    static function _clear()
    {
        unset( self::$_antecesors );
    }

}

?>
